package com.ryx.shiro;

import com.ryx.constants.Constant;
import com.ryx.exception.GlobalException;
import com.ryx.exception.code.BaseResponseCode;
import com.ryx.utils.JWTTokenUtil;
import com.ryx.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.TimeUnit;

/**
 * @BelongsPackage: com.ryx.shiro
 * @Author: 容永轩
 * @CreateTime: 2020-11-22
 * @Description:   自定义用户认证匹配方法   要继承HashedCredentialsMatcher 重写他的认证方法doCredentialsMatch
 */
@Slf4j
public class CustomHashedCredentialsMatcher extends HashedCredentialsMatcher {

    @Autowired
    private RedisUtil redisUtil;


    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

        CustomUsernamePasswordToken customUsernamePasswordToken = (CustomUsernamePasswordToken) token;

        String accessToken = (String) customUsernamePasswordToken.getCredentials();

        String userId = JWTTokenUtil.getUserId(accessToken);
        log.info("doCredentialsMatch:...userId{}",userId);

        //判断用户是否被删除
        if (redisUtil.hasKey(Constant.DELETED_USER_KEY+userId)){
            throw new GlobalException(BaseResponseCode.ACCOUNT_HAS_DELETED_ERROR);
        }
        //是否被锁定
        if (redisUtil.hasKey(Constant.ACCOUNT_LOCK_KEY+userId)){
            throw new GlobalException(BaseResponseCode.ACCOUNT_LOCK);
        }

        /**
         * 判断用户是否退出登录
         */
        if(redisUtil.hasKey(Constant.JWT_ACCESS_TOKEN_BLACKLIST+accessToken)){
            throw new GlobalException(BaseResponseCode.TOKEN_ERROR);
        }

        //校验token是否过期失效
        if ( !JWTTokenUtil.validateToken(accessToken)){
            throw new GlobalException(BaseResponseCode.TOKEN_PAST_DUE);
        }

        //判断用户是否被标记
        if(redisUtil.hasKey(Constant.JWT_REFRESH_KEY+userId)){
            /**
             * 判断用户是否已经刷新过
             */
            if(redisUtil.getExpire(Constant.JWT_REFRESH_KEY+userId, TimeUnit.MILLISECONDS)>JWTTokenUtil.getRemainingTime(accessToken)){
                throw new GlobalException(BaseResponseCode.TOKEN_PAST_DUE);
            }
        }


        return true;
    }
}
